#include "arprequstsender.h"
#include "utils.h"
#include <QDebug>

ArpRequstSender::ArpRequstSender(
        pcap_t* handle, std::shared_ptr<EthDev> eth_dev, QObject* parent) :
    QThread { parent }, handle_ { handle }, eth_dev_ { eth_dev }
{
    connect(&timer_, &QTimer::timeout, this, &ArpRequstSender::onTimeout);
    connect(this, &ArpRequstSender::started, this, &ArpRequstSender::onTimeout),
    moveToThread(this);
    start();
    // timer_.setInterval(1000 * 60);  // 设置定时器间隔为60秒
    // timer_.singleShot(1)
    // timer_.start();
}

ArpRequstSender::~ArpRequstSender()
{
    timer_.stop();
    this->quit();
    wait();
}

void ArpRequstSender::send_arp(pcap_t* handle, uint8_t* src_mac, uint8_t* src_ip, uint8_t* dst_ip)
{
    uint8_t     packet[60] = { 0 };
    eth_header* eth        = (eth_header*)packet;
    arp_packet* arp        = (arp_packet*)(packet + sizeof(eth_header));

    // 广播MAC
    memset(eth->dst_mac, 0xFF, 6);
    memcpy(eth->src_mac, src_mac, 6);
    eth->ether_type = htons(0x0806);  // ARP类型

    arp->htype = htons(1);       // 以太网
    arp->ptype = htons(0x0800);  // IPv4
    arp->hlen  = 6;
    arp->plen  = 4;
    arp->oper  = htons(1);  // ARP请求
    memcpy(arp->sha, src_mac, 6);
    memcpy(arp->spa, src_ip, 4);
    memset(arp->tha, 0, 6);  // 目标MAC设为0
    memcpy(arp->tpa, dst_ip, 4);

    if (pcap_sendpacket(handle, packet, 60) != 0)
    {
        printf("Error sending ARP request: %s\n", pcap_geterr(handle));
    }
}

void ArpRequstSender::onTimeout()
{
    if (QThread::currentThread() != this)
    {
        qDebug() << "onTimeout called from wrong thread";
        return;
    }
    QString str_mac = eth_dev_->mac;
    uint8_t src_mac[6];
    for (int i = 0; i < 6; i++)
    {
        src_mac[i] = str_mac.mid(i * 3, 2).toUInt(nullptr, 16);
    }
    int32_t src_ip =  eth_dev_->ip.toIPv4Address();
    int32_t mask_ip = eth_dev_->mask.toIPv4Address();
    int32_t network = src_ip & mask_ip;
    int32_t broadcast = network | ~mask_ip;

    uint32_t n_src = htonl(src_ip);
    uint32_t n_dst_ip;

    qDebug() << "local ip:" << eth_dev_->ip.toString();
    qDebug() << "from " << QHostAddress(network).toString() << " to " << QHostAddress(broadcast).toString();

    for(uint32_t ip = network + 1; ip < broadcast; ip++) {
        if (ip == src_ip) continue;

        n_dst_ip = htonl(ip);

        send_arp(handle_, src_mac, reinterpret_cast<uint8_t*>(&n_src), reinterpret_cast<uint8_t*>(&n_dst_ip));

        // 适当延迟，避免网络拥塞
        // usleep(1000);  // 10ms
        msleep(10);
    }
    qDebug() << "scan done";
}
